package com.itheima.aop;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect  /*声明这是一个切面或者是通知类*/
public class MyAdvice {

//    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
//    private void pt(){};


    @Pointcut("execution(int com.itheima.dao.BookDao.select(*))")
    private void pt2(){};

//    @Before("pt()")    /*@Before：前置通知，在原始方法运行之前执行*/
//    public void before(){
//        System.out.println("before advice ...");
//    }
//    @After("pt()")   /*@After：后置通知（最终通知），在原始方法运行之后执行*/
//    public void after() {
//        System.out.println("after advice ...");
//    }


    /*@Around：环绕通知，在原始方法运行的前后执行   ProceedingJoinPoint: spring找到目标方法，对其进行封装
                                  作用：目标方法执行,获取目标方法的参数,返回值,异常对象*/
    @Around("pt2()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice ...");
        Object[] args = pjp.getArgs();/*这里获取目标方法的参数 */
        System.out.println(args[0]);
        Signature signature = pjp.getSignature(); /*获取执行的签名对象*/
        System.out.println(signature.getDeclaringTypeName());  /*获取目标方法所在的类名*/
        System.out.println(signature.getName());/*获取目标方法方法名*/
        Integer ret = (Integer) pjp.proceed(); /*这里执行目标方法  获取返回值*/
        System.out.println(ret);
        System.out.println("around after advice ...");
        return ret;
    }


//    @AfterReturning("pt()")  /*@AfterReturning：返回后通知，在原始方法执行完毕后运行，且原始方法执行过程中未出现异常现象*/
//    public void afterReturning(){
//        System.out.println("afterReturning advice ...");
//    }

//    @AfterThrowing("pt()")  /*@AfterThrowing：抛出异常后通知，在原始方法执行过程中出现异常后运行*/
//    public void afterThrowing() {
//        System.out.println("afterThrowing advice ...");
//    }
}
